﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Threading.Tasks;
using Aioms.Models;
using Furion.DataEncryption;
using Furion.DynamicApiController;
using Furion.UnifyResult;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using QRCoder;
using SqlSugar;
using StackExchange.Profiling.Internal;

namespace Aioms.Controllers
{
    /// <summary>
    /// 员工接口
    /// </summary>
    [DynamicApiController]
    public class EmployeeController
    {
        private readonly ISqlSugarClient db; // 核心对象：拥有完整的SqlSugar全部功能
        public EmployeeController(ISqlSugarClient sqlSugarClient)
        {
            this.db = sqlSugarClient;
        }

        /// <summary>
        /// 员工列表
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="dpid"></param>
        /// <param name="content"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostList([FromForm] long eid, [FromForm] long dpid, [FromForm] string content, [FromForm] int pageIndex = 1, [FromForm] int pageSize = 10)
        {
            // 查询该企业下所有员工
            //List<long> epids = await db.Queryable<EmployeeEnterprise>().Where(ee => ee.Eid == eid).Select(ee => ee.Epid).ToListAsync();
            
            // 在该企业下指定范围内搜索员工
            RefAsync<int> total = 0;
            List<Employee> employees = await db.Queryable<Employee>()
                .Where(ep => ep.DefaultEid == eid)
                .Where(ep => ep.IsDel == 0)
                .WhereIF(dpid != 0, e => e.Dpid == dpid)
                .WhereIF(!string.IsNullOrEmpty(content), e => e.Realname.Contains(content) || e.Mobile.Contains(content)).ToPageListAsync(pageIndex, pageSize, total);
            foreach (var employee in employees)
            {
                List<long> rids = await db.Queryable<RoleEmployee>().Where(re => re.Eid == eid && re.Epid == employee.Id).Select(re => re.Rid).ToListAsync();
                if (rids?.Count > 0) { 
                    employee.Roles = await db.Queryable<Role>().Where(r => r.Eid == eid && rids.Contains(r.Id)).ToListAsync();
                }
                
            }
            UnifyContext.Fill(new { Total = total.Value });
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = employees,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 该企业所有员工字典
        /// </summary>
        /// <param name="eid"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostDictlist([FromForm] long eid)
        {
            // 在该企业下指定范围内搜索员工
            RefAsync<int> total = 0;
            var employees = await db.Queryable<Employee>()
                .Where(ep => ep.DefaultEid == eid)
                .Select(ep => new { Id = ep.Id, RealName = ep.Realname})
                .ToListAsync();
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = employees,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 停用/启用
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostTingyongqiyong([FromForm] long eid, [FromForm] long id, [FromForm] string status)
        {
            //EmployeeEnterprise employee_enterprise = await db.Queryable<EmployeeEnterprise>().Where(ee => ee.Eid == eid && ee.Epid == id).SingleAsync();
            //if (employee_enterprise == null) {
            //    return new JsonResult(new RESTfulResult<object>
            //    {
            //        StatusCode = -1,
            //        Succeeded = false,
            //        Data = null,
            //        Errors = "非法停用",
            //        Extras = UnifyContext.Take(),
            //        Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            //    });
            //}
            await db.Updateable<Employee>().SetColumns(ep => ep.Status == status).Where(ep => ep.Id == id).ExecuteCommandAsync();
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = null,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// PC端-安卓端查看员工个人信息接口
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostShow([FromForm] long eid, [FromForm] long id)
        {
            //EmployeeEnterprise employee_enterprise = await db.Queryable<EmployeeEnterprise>().Where(ee => ee.Eid == eid && ee.Epid == id).SingleAsync();
            //if (employee_enterprise == null)
            //{
            //    return new JsonResult(new RESTfulResult<object>
            //    {
            //        StatusCode = -1,
            //        Succeeded = false,
            //        Data = null,
            //        Errors = "非法查看员工信息",
            //        Extras = UnifyContext.Take(),
            //        Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            //    });
            //}
            Employee employee = await db.Queryable<Employee>().Mapper(ep => ep.Department, ep => ep.Dpid, ep => ep.Department.Id).Where(ep => ep.Id == id && ep.DefaultEid == eid).SingleAsync();
            List<long> rids = await db.Queryable<RoleEmployee>().Where(re => re.Eid == eid && re.Epid == employee.Id).Select(re => re.Rid).ToListAsync();
            if (rids?.Count > 0)
            {
                employee.Roles = await db.Queryable<Role>().Where(r => r.Eid == eid && rids.Contains(r.Id)).ToListAsync();
            }
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = employee,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 安卓端-退出登录接口
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostTuichu([FromForm] long eid, [FromForm] long id)
        {
            //EmployeeEnterprise employee_enterprise = await db.Queryable<EmployeeEnterprise>().Where(ee => ee.Eid == eid && ee.Epid == id).SingleAsync();
            //if (employee_enterprise == null)
            //{
            //    return new JsonResult(new RESTfulResult<object>
            //    {
            //        StatusCode = -1,
            //        Succeeded = false,
            //        Data = null,
            //        Errors = "非法退出",
            //        Extras = UnifyContext.Take(),
            //        Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            //    });
            //}
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = null,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 安卓端-员工修改密码
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="id"></param>
        /// <param name="password"></param>
        /// <param name="newpassword"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostXiugaimima([FromForm] long eid, [FromForm] long id, [FromForm] string password, [FromForm] string newpassword)
        {
            //EmployeeEnterprise employee_enterprise = await db.Queryable<EmployeeEnterprise>().Where(ee => ee.Eid == eid && ee.Epid == id).SingleAsync();
            //if (employee_enterprise == null)
            //{
            //    return new JsonResult(new RESTfulResult<object>
            //    {
            //        StatusCode = -1,
            //        Succeeded = false,
            //        Data = null,
            //        Errors = "非法退出",
            //        Extras = UnifyContext.Take(),
            //        Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            //    });
            //}
            Employee employee = await db.Queryable<Employee>().Where(e => e.Id == id).SingleAsync();
            if (!employee.Password.Equals(MD5Encryption.Encrypt(password))) {
                return new JsonResult(new RESTfulResult<object>
                {
                    StatusCode = -1,
                    Succeeded = false,
                    Data = null,
                    Errors = "原密码错误",
                    Extras = UnifyContext.Take(),
                    Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                });
            }
            await db.Updateable<Employee>().Where(e => e.Id == id).SetColumns(e => e.Password == MD5Encryption.Encrypt(newpassword)).ExecuteCommandAsync();
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = null,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 员工删除
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostDelete([FromForm] long eid, [FromForm] long id)
        {
            //EmployeeEnterprise employee_enterprise = await db.Queryable<EmployeeEnterprise>().Where(ee => ee.Eid == eid && ee.Epid == id).SingleAsync();
            //if (employee_enterprise == null)
            //{
            //    return new JsonResult(new RESTfulResult<object>
            //    {
            //        StatusCode = -1,
            //        Succeeded = false,
            //        Data = null,
            //        Errors = "非法删除",
            //        Extras = UnifyContext.Take(),
            //        Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            //    });
            //}
            //await db.Updateable<Employee>().SetColumns(ep => ep.DefaultEid == 0).Where(ep => ep.Id == id && ep.DefaultEid == eid).ExecuteCommandAsync();
            await db.Updateable<Employee>().SetColumns(ep => ep.IsDel == 1).Where(ep => ep.Id == id && ep.DefaultEid == eid).ExecuteCommandAsync();
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = null,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 增加员工
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="employee"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostSave([FromForm] long eid, [FromForm] Employee employee)
        {
            // 判断该员工是否存在，有的话不允许添加
            Employee existsemployee = await db.Queryable<Employee>().Where(ep => ep.Mobile == employee.Mobile).SingleAsync();
            if (existsemployee != null) {
                return new JsonResult(new RESTfulResult<object>
                {
                    StatusCode = -1,
                    Succeeded = false,
                    Data = null,
                    Errors = "该手机号已被添加",
                    Extras = UnifyContext.Take(),
                    Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
                });
            }
            employee.Password = MD5Encryption.Encrypt(employee.Password);
            employee.Token = MD5Encryption.Encrypt(DateTime.Now.ToString());
            Employee last_employee = await db.Insertable<Employee>(employee).ExecuteReturnEntityAsync();

            // 在该企业添加角色
            if (employee.Rids?.Length > 0) {
                await db.Deleteable<RoleEmployee>().Where(re => re.Eid == eid && employee.Rids.ToList().Contains(re.Epid)).ExecuteCommandAsync();
                foreach (var rid in employee.Rids)
                {
                    await db.Insertable<RoleEmployee>(new RoleEmployee { Eid = eid, Epid = last_employee.Id, Rid = rid }).ExecuteCommandAsync();
                }
            }

            // 在该企业中添加员工
            //EmployeeEnterprise employeeEnterprise = new();
            //employeeEnterprise.Eid = eid;
            //employeeEnterprise.Epid = last_employee.Id;
            //await db.Insertable<EmployeeEnterprise>(employeeEnterprise).ExecuteCommandAsync();
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = last_employee,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 修改员工
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="employee"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostUpdate([FromForm] long eid, [FromForm] Employee employee)
        {
            Employee existsemployee = await db.Queryable<Employee>().Where(ep => ep.Id == employee.Id).SingleAsync();
            if (string.IsNullOrEmpty(employee.Password))
            {
                employee.Password = existsemployee.Password;
            }
            else {
                employee.Password = MD5Encryption.Encrypt(employee.Password);
            }
            await db.Updateable<Employee>(employee).ExecuteCommandAsync();

            // 在该企业添加角色
            await db.Deleteable<RoleEmployee>().Where(re => re.Eid == eid && re.Epid == employee.Id).ExecuteCommandAsync();
            if (employee.Rids?.Length > 0)
            {
                foreach (var rid in employee.Rids)
                {
                    await db.Insertable<RoleEmployee>(new RoleEmployee { Eid = eid, Epid = employee.Id, Rid = rid }).ExecuteCommandAsync();
                }
            }
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = null,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 安卓端-获取VR眼镜端二维码
        /// </summary>
        /// <param name="epid"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostGetqrcode([FromForm] long epid)
        {
            Employee employee = await db.Queryable<Employee>().Where(ep => ep.Id == epid).SingleAsync();
            //Enterprise enterprise = await db.Queryable<Enterprise>().Where(e => e.Id == employee.DefaultEid).SingleAsync();
            //JObject data = JObject.FromObject(employee);
            //data.Add("enterprise", JObject.FromObject(enterprise));
            JObject data = new();
            data.Add("id", employee.Id);
            data.Add("realname", employee.Realname);
            data.Add("token", employee.Token);
            data.Add("eid", employee.DefaultEid);

            var imgType = Base64QRCode.ImageType.Jpeg;
            QRCodeGenerator qrGenerator = new();
            QRCodeData qrCodeData = qrGenerator.CreateQrCode(data.ToJson(), QRCodeGenerator.ECCLevel.Q);
            Base64QRCode qrCode = new(qrCodeData);
            string qrCodeImageAsBase64 = qrCode.GetGraphic(10, Color.Black, Color.White, false, imgType);
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = qrCodeImageAsBase64,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        /// <summary>
        /// 获取用户权限
        /// </summary>
        /// <param name="eid"></param>
        /// <param name="epid"></param>
        /// <returns></returns>
        public async Task<IActionResult> PostGetpermission([FromForm] long eid, [FromForm] long epid, [FromForm] string type)
        {
            type = type == null ? "url" : type;
            JArray data = new();
            // 获取当前用户所有角色
            List<long> rids = await db.Queryable<RoleEmployee>().Where(re => re.Eid == eid && re.Epid == epid).Select(re => re.Rid).ToListAsync();
            if (rids?.Count > 0)
            {
                // 获取当前角色的所有权限ID
                List<long> pmids = await db.Queryable<RolePermission>().Where(re => re.Eid == eid).Where(rp => rids.Contains(rp.Rid)).Select(rp => rp.Pmid).ToListAsync();
                if (pmids?.Count > 0)
                {
                    // 去重pmids
                    pmids = pmids.Distinct().ToList();
                    foreach (var pmid in pmids)
                    {
                        await GetAllParentIdByPmid(eid, pmid);
                    }
                    // 该角色所有权限去重
                    allParentPmids = allParentPmids.Distinct().ToList();
                    data = GetRolePermissionTreeData(eid, 0, type, pmids).Result;
                }
            }
            return new JsonResult(new RESTfulResult<object>
            {
                StatusCode = 200,
                Succeeded = true,
                Data = data,
                Errors = null,
                Extras = UnifyContext.Take(),
                Timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
            });
        }

        List<long> allParentPmids = new(); // 所有权限ID，后面要去重
        [NonAction]
        public async Task GetAllParentIdByPmid(long eid, long pmid)
        {
            // 查询当前节点信息
            EnterprisePermission enterprisepermission = await db.Queryable<EnterprisePermission>().Where(ee => ee.Eid == eid && ee.Bspmid == pmid).SingleAsync();
            if (enterprisepermission != null)
            {
                allParentPmids.Add(pmid);
                await GetAllParentIdByPmid(eid, enterprisepermission.ParentId);
            }
        }

        [NonAction]
        public async Task<JArray> GetRolePermissionTreeData(long eid, long bspmid, string type, List<long> pmids)
        {
            JArray data = new();
            if (type.Equals("menu"))
            {
                List<EnterprisePermission> enterprisepermissions = await db.Queryable<EnterprisePermission>().Where(ep => ep.Eid == eid).Where(ep => ep.ParentId == bspmid && ep.Type == "menu").Where(ep => ep.Status == 1).Where(ep => allParentPmids.Contains(ep.Bspmid)).OrderBy("sort_id asc").ToListAsync();
                if (enterprisepermissions?.Count > 0)
                {
                    foreach (var enterprisepermission in enterprisepermissions)
                    {
                        JObject jo_enterprisepermission = JObject.FromObject(enterprisepermission);
                        jo_enterprisepermission.Add("children", GetRolePermissionTreeData(eid, enterprisepermission.Bspmid, type, pmids).Result);
                        data.Add(jo_enterprisepermission);
                    }
                }
            }
            else if (type.Equals("button"))
            {
                List<EnterprisePermission> enterprisepermissions;
                if (bspmid == 0)
                { // 取所有的权限
                    enterprisepermissions = await db.Queryable<EnterprisePermission>().Where(ep => ep.Eid == eid).Where(ep => ep.Type == "button").Where(ep => ep.Status == 1).Where(ep => allParentPmids.Contains(ep.Bspmid)).OrderBy("sort_id asc").ToListAsync();
                }
                else
                {
                    enterprisepermissions = await db.Queryable<EnterprisePermission>().Where(ep => ep.Eid == eid).Where(ep => ep.ParentId == bspmid && ep.Type == "button").Where(ep => ep.Status == 1).Where(ep => allParentPmids.Contains(ep.Bspmid)).OrderBy("sort_id asc").ToListAsync();
                }
                data = JArray.FromObject(enterprisepermissions);
            }
            else
            {
                List<EnterprisePermission> enterprisepermissions = await db.Queryable<EnterprisePermission>().Where(ep => ep.Eid == eid).Where(ep => ep.ParentId == bspmid).Where(ep => ep.Status == 1).Where(ep => allParentPmids.Contains(ep.Bspmid)).OrderBy("sort_id asc").ToListAsync();
                if (enterprisepermissions?.Count > 0)
                {
                    foreach (var enterprisepermission in enterprisepermissions)
                    {
                        JObject jo_enterprisepermission = JObject.FromObject(enterprisepermission);
                        jo_enterprisepermission.Add("children", GetRolePermissionTreeData(eid, enterprisepermission.Bspmid, type, pmids).Result);
                        data.Add(jo_enterprisepermission);
                    }
                }

            }
            return data;
        }
        
        /*
        [NonAction]
        public async Task<JArray> GetRolePermissionTreeData111(long eid, long pid, string type)
        {
            JArray data = new();
            if (type.Equals("menu"))
            {
                List<EnterprisePermission> enterprisepermissions = await db.Queryable<EnterprisePermission>().Where(ep => ep.Eid == eid).Where(ep => ep.ParentId == pid && ep.Type == "menu").Where(ep => ep.Status == 1).Where(ep => allParentPmids.Contains(ep.Id)).OrderBy("sort_id asc").ToListAsync();
                if (enterprisepermissions?.Count > 0)
                {
                    foreach (var enterprisepermission in enterprisepermissions)
                    {
                        JObject jo_enterprisepermission = JObject.FromObject(enterprisepermission);
                        jo_enterprisepermission.Add("children", GetRolePermissionTreeData(eid, enterprisepermission.Id, type).Result);
                        data.Add(jo_enterprisepermission);
                    }
                }
            }
            else if (type.Equals("button"))
            {
                List<EnterprisePermission> enterprisepermissions;
                if (pid == 0)
                { // 取所有的权限
                    enterprisepermissions = await db.Queryable<EnterprisePermission>().Where(ep => ep.Eid == eid).Where(ep => ep.Type == "button").Where(ep => ep.Status == 1).Where(ep => allParentPmids.Contains(ep.Id)).OrderBy("sort_id asc").ToListAsync();
                }
                else
                {
                    enterprisepermissions = await db.Queryable<EnterprisePermission>().Where(ep => ep.Eid == eid).Where(ep => ep.ParentId == pid && ep.Type == "button").Where(ep => ep.Status == 1).Where(ep => allParentPmids.Contains(ep.Id)).OrderBy("sort_id asc").ToListAsync();
                }
                data = JArray.FromObject(enterprisepermissions);
            }
            else
            {
                List<EnterprisePermission> enterprisepermissions = await db.Queryable<EnterprisePermission>().Where(ep => ep.Eid == eid).Where(ep => ep.ParentId == pid).Where(ep => ep.Status == 1).Where(ep => allParentPmids.Contains(ep.Id)).OrderBy("sort_id asc").ToListAsync();
                if (enterprisepermissions?.Count > 0)
                {
                    foreach (var enterprisepermission in enterprisepermissions)
                    {
                        JObject jo_enterprisepermission = JObject.FromObject(enterprisepermission);
                        jo_enterprisepermission.Add("children", GetRolePermissionTreeData(eid, enterprisepermission.Id, type).Result);
                        data.Add(jo_enterprisepermission);
                    }
                }

            }
            return data;
        }*/
    }
}
